<?php
/**
 * Service_Essence
 *
 * Класс Service_Essence осуществляет работу с типами сущностей (ID, имя)
 *
 * @author 
 * @version 1.0
 */
class Service_Essence {
	// ассоциативный массив с названиями сущностей
	//
	// essenceName - название сущности: article || comment || video_archive || user_event и т.д.
	//	
	// так же essenceName является названием таблицы в системе с учетом префикса, 
	// например у сущности article в проекте prprof название оснвной таблицы должно быть prprof_article
	//
	// essenceTypeId - идентификатор имени сущности, используется для сокращенной записи в БД
	// у каждой сущности уникальный id в пределах проекта
	// так же в разных проектах essenceTypeId одинаковых сущностей должны совпадать	
	//
	// idFieldName - название поля с id сущности в таблице, по умолчанию название поля - id_article || id_comment и т.д.
	// idFieldName введена потому что может использоваться поле id_event в таблице prprof_user_event 
	private static function getArrEssence(){
		$arrEssences = array(
			0 => array("essenceName" => "user_events", "essenceTypeId" => 1, "idFieldName" => "id_event"),
			1 => array("essenceName" => "comment", "essenceTypeId" => 2, "idFieldName" => "id_comment"),
			2 => array("essenceName" => "bulletin_board", "essenceTypeId" => 3, "idFieldName" => "id_bulletin_board"), // объявления
			3 => array("essenceName" => "bulletin_board_section", "essenceTypeId" => 4, "idFieldName" => "id_section") // разделы для объявлений
		);
		return $arrEssences;
	}
	
	
	
	
	
  /**
   * Получение имени сущности по идентификатору
   *
   * @param int $essenceNumber
   * @return string
   */	
	public static function getEssenceTypeName($essenceNumber){
	  	if (!is_numeric($essenceNumber))
	  		return $essenceNumber;
	  	foreach (self::getArrEssence() as $arrEssence){
	  		if ($arrEssence["essenceTypeId"] == $essenceNumber)
	  			return $arrEssence["essenceName"];
	  	}
	  	return false;
	}
	
  /**
   * Получение идентификатора сущности по имени
   *
   * @param string $essenceName
   * @return int
   */
	public static function getEssenceTypeIDByName($essenceName) {
	  	foreach (self::getArrEssence() as $arrEssence){
	  		if ($arrEssence["essenceName"] == $essenceName)
	  			return $arrEssence["essenceTypeId"];
	  	}
	  	return false;
	}
	
	public static function getEssenceIdFieldNameById($essenceNumber){
	  	foreach (self::getArrEssence() as $arrEssence){
	  		if ($arrEssence["essenceTypeId"] == $essenceNumber)
	  			return $arrEssence["idFieldName"];
	  	}
	  	return false;		
	}
	
	public static function getEssenceIdFieldNameByName($essenceName){
	  	foreach (self::getArrEssence() as $arrEssence){
	  		if ($arrEssence["essenceName"] == $essenceName)
	  			return $arrEssence["idFieldName"];
	  	}
	  	return false;		
	}
	
	/**
	 * Метод возвращает названия поля таблицы с id сущности
	 * по essenceName или essenceId
	 *
	 * @param unknown_type $essenceType
	 */
	public static function getEssenceIdFieldName($essenceType){
		if (is_numeric($essenceType))
			return self::getEssenceIdFieldNameById($essenceType);
		else 
			return self::getEssenceIdFieldNameByName($essenceType);
	}
	
	
	
	
	
	
	
	
	
	
	
  
  /**
   * Возвращает те сущности, к которым выставляются комментарии
   * необходимо для получения всех комментариев пользователя
   * при добавлении новой сущности с возможностью комментирования, добавлять ее сюда
   *
   * @return unknown
   */
	public static function getEssenceTypeNameForUserComment(){
		return array('article', 'question', 'solution', 'community', 'tutorial_lesson', 'content_request', 'feed_back');
	}

	public static function getEssenceUrl($essenceType, $idEssence){

		$essenceTypeNum = self::getEssenceTypeID($essenceType);
		switch ($essenceTypeNum) {
		    	case 1:
		        return 'article/' . $idEssence;
		    	case 5:
		    		return 'question/' . $idEssence;
		      case 7:{
		      	$objTutorial = new Tutorial();
		      	return $objTutorial->getLessonUrl($idEssence, true);
		      }
		      case 10:
		      	return 'solution/'.$idEssence;
		      case 11:
		      	return 'community/'.$idEssence;
		      case 17:
      			return 'bug/'.$idEssence;
		      case 19:
		      	return 'crequest/'.$idEssence;
		  	  default:
		  		return false;
		  	}
	}
	



  /**
   * Получение человеческое имени сущности по идентификатору
   */
  public static function getEssenceTypeHumanName($essenceNumber, $many = false) {
  	if (!is_numeric($essenceNumber))
  		return $essenceNumber;
    switch ($essenceNumber) {
      case 1:
      	return $many ? 'Статьи' : 'Статья';
  	  case 2:
  		return $many ? 'Комментарии' : 'Комментарий';
  	  case 3:
  		return $many ? 'Пользователи' : 'Пользователь';
  	  case 4:
  		return '';
      case 5:
        return $many ? 'Вопросы' : 'Вопрос';
      case 6:
      	return $many ? 'Ответы' : 'Ответ';
      case 7:
      	return $many ? 'Уроки' : 'Урок';
      case 8:
      	return $many ? 'Комплексы' : 'Комплекс';
      case 9:
        return $many ? 'Темы' : 'Тема';
      case 10:
      	return $many ? 'Готовые решения' : 'Готовое решение';
      case 11:
      	return $many ? 'Сообщества' : 'Сообщество';
      case 12:
      	return $many ? 'Предложения тем' : 'Предложение темы';
      case 13:
      	return $many ? 'Предложения' : 'Предложение';
      case 14:
      	return $many ? 'Блоги разработчиков' : 'Блог разработсиков';
      case 15:
      	return $many ? 'Языки программирования' : 'Язык программирования';
      case 16:
      	return $many ? 'Разделы' : 'Раздел';
      case 17:
      	return $many ? 'Обратные связи' : 'Обратная связь';
      case 18:
      	return $many ? 'Самоучители' : 'Самоучитель';
      case 19:
      	return $many ? 'Заявки на контент' : 'Заявка на контент';
      case 20:
      	return $many ? 'Поиск работы' : 'Поиск работы';
  	  default:
  		return false;
  	}
  }

  public static function getEssenceTypeHumanNameLC($essenceNumber, $many = false) {
    return strtolowerU(self::getEssenceTypeHumanName($essenceNumber, $many));
  }

  /**
   * Получение идентификатора сущности по любому параметру
   *
   * @param mixed $essenceType
   * @return int
   */
  public static function getEssenceTypeID($essenceType) {
    if(is_numeric($essenceType)) return $essenceType;
    else return (int)self::getEssenceTypeIDByName($essenceType);
    return $essenceType;
  }


    public static function getEssenceTypeRootUrlByID($essenceTypeId) {
    switch ($essenceTypeId) {

    	case 1:
      	return 'articles';
  //  		case 'comment':
  //  			return 2;
  //  		case 'user':
  //  	  	return 3;
  //  		case '':
  //  			return 4;
      case 5:
      	return 'questions';
  //      case 'answer':
  //      	return 6;
      case 7:
       	return 'tutorials';
  //      case 'tutorial_complex':
  //      	return 8;
  //      case 'tutorial_theme':
  //      	return 9;
      case 10:
       	return 'solutions';
      case 11:
       	return 'communities';
  //      case 'tutorial_theme_offer':
  //       	return 12;
  //			case 'offer':
  //      	return 13;
  //			case 'developer_blog':
  //      	return 14;
  //			case 'programming_language':
  //      	return 15;
  //      case 'folder':
  //      	return 16;
  //      case 'feed_back':
  //      	return 17;
  //      case 'tutorial':
  //      	return 18;
  //      case 19:
  //       	return 'crequest';
  		default:
  		 	return false;
  	}
  }


  /**
   * Проверяет, существует ли сущность заданного типа
   *
   * @param int $essenceId
   * @param string|int $essenceType
   * @return bool
   */
  public static function checkIfEssenceExists ($essenceId, $essenceType) {
    $objDB = Service_Database::instance();
    $essenceType = Service_Essence::getEssenceTypeID($essenceType);
    $essenceName = Service_Essence::getEssenceTypeName($essenceType);
    $essenceIdField = Service_Essence::getEssenceIdFieldName($essenceType);
    $stmt = "SELECT `" . DB_PREFIX.$essenceName . "`." . "`" . $essenceIdField . "`
             FROM `" . DB_PREFIX.$essenceName . "`
             WHERE `" . DB_PREFIX.$essenceName . "`." . "`" . $essenceIdField . "`='" . $essenceId . "'";
    return sizeof($objDB->select($stmt)) > 0;
  }

  public static function getOne ($essenceId, $essenceType) {
    $objDB = Service_Database::instance();
    $essenceType = Service_Essence::getEssenceTypeID($essenceType);
    $essenceName = Service_Essence::getEssenceTypeName($essenceType);
    $addFields = "";
    $addJoins = "";
    switch ($essenceType) {
      case 1:
        $addFields = ", `article`.`ID_essence` AS `ID_folder`";
        break;
      case 7:
        $addFields = ", `tutorial`.`ID_folder`";
        $addJoins = "LEFT JOIN `tutorial_theme` ON `tutorial_theme`.`ID_tutorial_theme` = `tutorial_lesson`.`ID_tutorial_theme`
                     LEFT JOIN `tutorial` ON `tutorial`.`ID_tutorial`=`tutorial_theme`.`ID_tutorial`";
        break;
      default:

    }
    $stmt = "SELECT `" . $essenceName . "`.*" . $addFields . "
             FROM `" . $essenceName . "`
             " . $addJoins . "
             WHERE `" . $essenceName . "`." . "`ID_" . $essenceName . "`='" . $essenceId . "'";
    return $objDB->selectOne($stmt);
  }

  /**
   * Формирует очередной элемент массива с данными обо всех сущностях для отображения элемента управления "Voting"
   *
   * @param array $arrEssence
   * @param unknown_type $type
   * @return unknown
   */
  public static function makeJsonVotingArrayElement($arrEssence, $type/*, $isDisabled = false*/) {
    $arrVotingControlsElement = array();
    if (is_string($type))
      $type = (int)Service_Essence::getEssenceTypeID($type);
    else
      if (!is_numeric($type))
        return false;
    $arrVotingControlsElement = array(
        /*"disabled" => $isDisabled,*/
        "essenceType" => $type,
        "ID_essence" => $arrEssence['ID_' . Service_Essence::getEssenceTypeName($type)]
      );
    return $arrVotingControlsElement;
  }

  /**
   * Возвращает массив с информацией и типах сущностей для общего облака тегов
   *
   * @return array
   */
  public static function getMainTagsEssencesArray() {
    return array(
      array(self::getEssenceTypeIDByName('question'), 'question', 'Вопросы'),
      array(self::getEssenceTypeIDByName('article'), 'articles', 'Статьи'),
      array(self::getEssenceTypeIDByName('tutorial_lesson'), 'tutorials', 'Самоучитель'),
      array(self::getEssenceTypeIDByName('solution'), 'solutions', 'Решения')
    );
  }

  /**
   * Получаем информацию о сущностях по ID & essence_type (в массиве)
   *
   * @param array $arrEssencesData - массив с данными о сущностях
   * @return array - массим с информацие по этим сущностям
   */
  public static function getEssencesByItsInfo($arrEssencesData) {
    //Получаем типы сущностей
    $arrEssencesTypes = array_unique(getArrayColumn($arrEssencesData, 'essence_type'));
    $arrEssencesIDs = array();
    for ($i = 0; $i < sizeof($arrEssencesData); $i++) {
      $arrEssencesIDs[$arrEssencesData[$i]['essence_type']][] = $arrEssencesData[$i]['ID_essence'];
    }
//    echo sizeof($arrEssencesData);
    $arrEssencesDataResult = array();
    foreach ($arrEssencesTypes as $tId => $essenceType) {
      $arrEssencesDataResult = array_merge($arrEssencesDataResult, self::getEssencesByIDs($arrEssencesIDs[$essenceType], $essenceType));
    }
//    echo '<pre>';print_r($arrEssencesDataResult);echo '</pre>';
    return $arrEssencesDataResult;
  }

  /**
   * Получаем информацию о сущностях по массиву идентификаторов и типу
   *
   * @param array $arrEssencesIDs
   * @param int|string $essenceType
   * @return array
   */
  public static function getEssencesByIDs($arrEssencesIDs, $essenceType) {
    $objDB = Service_Database::instance();
    $essenceName = Service_Essence::getEssenceTypeName($essenceType);
    $stmt = "SELECT `" . $essenceName . "`.`ID_" . $essenceName . "`,";
    if ($essenceName == 'community'){
    	$stmt .= "`folder`.`name`, `" . $essenceName . "`.`ID_user`
             FROM `" . $essenceName . "`
             LEFT JOIN `folder` ON `folder`.`ID_folder` = `community`.`ID_community` 
						WHERE `" . $essenceName . "`.`ID_" . $essenceName . "` IN ('" . join("', '", $arrEssencesIDs) . "')";
    }
    else {
	    if ($essenceName != "feed_back") $stmt .= "`" . $essenceName . "`.`name`,";
	    $stmt .= "`" . $essenceName . "`.`ID_user`
	             FROM `" . $essenceName . "`
	             WHERE `" . $essenceName . "`.`ID_" . $essenceName . "` IN ('" . join("', '", $arrEssencesIDs) . "')";    	
    }
    
/*    echo count($arrEssencesIDs) . " - " . count(getArrayColumn($objDB->select($stmt), "ID_" . $essenceName)) . "<br />";
    $arr1 = array();
    for ($i=0;$i<sizeof($arrEssencesIDs);$i++)
      $arr1[]['ID_' . $essenceName] = $arrEssencesIDs[$i];
    echo '<pre>'; print_r(getDataArraysFullDiff($arr1, $objDB->select($stmt), "ID_" . $essenceName, "ID_" . $essenceName));echo '</pre>';
    echo $stmt . "<br />";*/
    return $objDB->select($stmt);
  }

  /**
   * Обрабатываем текст, создаём кат
   *
   * @param array $arrPost - (внутри должен быть элемент $arrPost['text'])
   */
  public static function makeCutOfText(&$arrPost) {
    $text = $arrPost['text'];
    $cuttedText = '';
    $cutText = '';
    $fullText = '';
    $k = 0;
		while (is_integer(strpos($text, '<cut'))) {
      $k++;
			$posCutStart = strpos($text, '<cut>');
      $posCutEnd = strpos($text, '</cut>');
      $posCutTextStart = strpos($text, 'cuttext=', $posCutStart);
      //Solve magic quotes trouble
      $addDigit = !(!get_magic_quotes_gpc() && !get_magic_quotes_runtime()) ? 1 : 0;
      $posCutTextEnd = strpos($text, '"', $posCutTextStart + 10 + $addDigit);
      $cutText = substr($text, $posCutTextStart + 10 + $addDigit, $posCutTextEnd - $posCutTextStart - (10 + $addDigit));
      $fullText .= substr($text, 0, $posCutStart) . '<cut><span class="cut_text" id="cut_block_' . $k . '" cuttext="' . $cutText . '">' . getTagBetweenValueFirst(getTagBetweenValueFirst($text, 'cut'), 'span') . '</span></cut>'; //?????»???‹?? ?‚?µ?????‚
      $cuttedText .= substr($text, 0, $posCutStart) . '<a href="link_to_the_full_version#cut_block_' . $k . '">' . $cutText . '</a><br>'; //???€?°?‚?????? ?‚?µ?????‚
      $text = substr($text, $posCutEnd + 6);
    }
    $cuttedText .= $text;
    $fullText .= $text;
    $arrPost['text'] = $fullText;
    $arrPost['cut_text'] = $cuttedText;
   return true;
  }

  /*Обработка избранных*/
  /**
   * Добавление
   *
   * @param int $id
   * @param int|string $essenceType
   */
  public static function makeFavorite($id, $essenceType) {
    if (self::_checkIfFavorite($id, $essenceType))
      return false;
    $objDB = Service_Database::instance();
    $essenceTypeId = (int)Service_Essence::getEssenceTypeID($essenceType);
    $objSession = User_Session::instance();
    self::_incrementEssenceFavoritedAmount($id, $essenceType);
    self::_incrementUserFavoritesAmount($essenceType);
    //Вставляем новую запись о том, что пользователь выбрал что-то в избранное
    return $objDB->insert('user_essence_favorite', array('ID_user' => $objSession->getUserId(),
                                                         'ID_essence' => $id,
                                                         'essence_type' => $essenceTypeId));
  }
  /**
   * Удаление
   *
   * @param int $id
   * @param int|string $essenceType
   */
  public static function unFavorite($id, $essenceType) {
    if (!self::_checkIfFavorite($id, $essenceType))
      return false;
    $objDB = Service_Database::instance();
    $essenceTypeId = (int)Service_Essence::getEssenceTypeID($essenceType);
    $objSession = User_Session::instance();
    self::_decrementEssenceFavoritedAmount($id, $essenceType);
    self::_decrementUserFavoritesAmount($essenceType);
    //удаляем запись о том, что пользователь выбрал что-то в избранное
    return $objDB->delete('user_essence_favorite', array('ID_user' => $objSession->getUserId(),
                                                         'ID_essence' => $id,
                                                         'essence_type' => $essenceTypeId));
  }
  private static function _checkIfFavorite($id, $essenceType) {
    $objDB = Service_Database::instance();
    $essenceTypeId = (int)Service_Essence::getEssenceTypeID($essenceType);
    $objSession = User_Session::instance();
    $stmt = "SELECT `ID_user`
             FROM `user_essence_favorite`
             WHERE `ID_user`=" . $objSession->getUserId() . "
             AND `ID_essence`=" . $id . "
             AND `essence_type`=" . $essenceTypeId;
    return sizeof($objDB->select($stmt)) > 0;
  }
  private static function _incrementUserFavoritesAmount($essenceType) {
    $objDB = Service_Database::instance();
    $objSession = User_Session::instance();
    $essenceTypeId = (int)Service_Essence::getEssenceTypeID($essenceType);
    $essenceName = Service_Essence::getEssenceTypeName($essenceTypeId);
    $stmt = 'UPDATE `user` SET `favorite_' . $essenceName . '_amount`=`favorite_' . $essenceName . '_amount`+1 WHERE `ID_user`=' . $objSession->getUserId();
    return $objDB->query($stmt);
  }
  private static function _decrementUserFavoritesAmount($essenceType) {
    $objDB = Service_Database::instance();
    $objSession = User_Session::instance();
    $essenceTypeId = (int)Service_Essence::getEssenceTypeID($essenceType);
    $essenceName = Service_Essence::getEssenceTypeName($essenceTypeId);
    $stmt = 'UPDATE `user` SET `favorite_' . $essenceName . '_amount`=`favorite_' . $essenceName . '_amount`-1 WHERE `ID_user`=' . $objSession->getUserId();
    return $objDB->query($stmt);
  }
  private static function _incrementEssenceFavoritedAmount($id, $essenceType) {
    $objDB = Service_Database::instance();
    $essenceTypeId = (int)Service_Essence::getEssenceTypeID($essenceType);
    $essenceName = Service_Essence::getEssenceTypeName($essenceTypeId);
    $stmt = 'UPDATE `' . $essenceName . '` SET `favored_amount`=`favored_amount`+1 WHERE `ID_' . $essenceName . '`=' . $id;
    return $objDB->query($stmt);
  }
  private static function _decrementEssenceFavoritedAmount($id, $essenceType) {
    $objDB = Service_Database::instance();
    $essenceTypeId = (int)Service_Essence::getEssenceTypeID($essenceType);
    $essenceName = Service_Essence::getEssenceTypeName($essenceTypeId);
    $stmt = 'UPDATE `' . $essenceName . '` SET `favored_amount`=`favored_amount`-1 WHERE `ID_' . $essenceName . '`=' . $id;
    return $objDB->query($stmt);
  }
  public static function getAllUserFavorites() {
    $objDB = Service_Database::instance();
    $objSession = User_Session::instance();
    $arrAllowedTypes = array(1,7,10/*,5*/); #типы, которые разрешается добавлять в избранные
    $arrAllFavorites = array();
    foreach ($arrAllowedTypes as $typeId) {
      $essenceName = Service_Essence::getEssenceTypeName($typeId);
      $fields = '`'.$essenceName.'`.`ID_'.$essenceName.'`, `'.$essenceName.'`.`name` AS `'.$essenceName.'_name`, `'.$essenceName.'`.`tags`, `'.$essenceName.'`.`creation`, `user`.`login`';
      $joins = 'LEFT JOIN `'.$essenceName.'` ON `fav_sub_table`.`ID_essence`=`'.$essenceName.'`.`ID_'.$essenceName.'`
                LEFT JOIN `user` ON `user`.`ID_user`=`'.$essenceName.'`.`ID_user`';
      switch ($typeId) {
        case 1:
          $fields .= ", `article`.`ID_essence` AS `ID_folder`, `article`.`essence_type`";
          $joins .= 'LEFT JOIN `folder` ON `article`.`ID_essence`=`folder`.`ID_folder`';
          break;
        case 7:
          $fields .= ", `tutorial`.`ID_folder`, `tutorial`.`url_name`, `tutorial`.`name` AS `tutorial_name`, `tutorial_theme`.`ID_tutorial_theme`, `tutorial_theme`.`name` AS `theme_name`, `tutorial_lesson`.`name` AS `lesson_name`";
          $joins .= "LEFT JOIN `tutorial_theme` ON `tutorial_theme`.`ID_tutorial_theme` = `tutorial_lesson`.`ID_tutorial_theme`
                     LEFT JOIN `tutorial` ON `tutorial`.`ID_tutorial`=`tutorial_theme`.`ID_tutorial`";
          $joins .= 'LEFT JOIN `folder` ON `tutorial`.`ID_folder`=`folder`.`ID_folder`';
          break;
        case 10:
          $fields .= ', `'.$essenceName.'`.`ID_folder`';
          $joins .= 'LEFT JOIN `folder` ON `'.$essenceName.'`.`ID_folder`=`folder`.`ID_folder`';
          break;
        /*case 5:
          $fields .= ', `'.$essenceName.'`.`ID_folder`';
          $joins .= 'LEFT JOIN `folder` ON `'.$essenceName.'`.`ID_folder`=`folder`.`ID_folder`';
          break;*/
      }
      $fields .= ', `folder`.`name` as `folder_name`';
      $stmt = 'SELECT '.$fields.'
               FROM (
                 SELECT * FROM `user_essence_favorite`
                 WHERE `user_essence_favorite`.`ID_user`='.$objSession->getUserId().'
                   AND `user_essence_favorite`.`essence_type`='.$typeId.'
               ) AS `fav_sub_table`
               '.$joins.'
               ORDER BY `'.$essenceName.'`.`creation` DESC';
      $arrAllFavorites[$typeId] = $objDB->select($stmt);
    }
    return $arrAllFavorites;
  }

    public static function getAuthor($id, $typeId) {
    $essenceName = Service_Essence::getEssenceTypeName($typeId);
    $objDB = Service_Database::instance();
    $stmt = "SELECT `ID_user`
             FROM `" . $essenceName . "`
             WHERE `ID_" . $essenceName . "`=" . $id;
    return $objDB->selectSimpleField($stmt);
  }

}
?>